"""
A股指数期权自动交易系统主入口
"""
import asyncio
import logging
from contextlib import asynccontextmanager
from typing import Dict, List, Optional

from fastapi import FastAPI, WebSocket, WebSocketDisconnect
from fastapi.middleware.cors import CORSMiddleware
from fastapi.staticfiles import StaticFiles

from .core.config import settings
from .core.database import db_manager
from .core.logger import setup_logging
from .services.strategy_engine import strategy_engine
from .services.market_data import market_data_service
from .services.risk_manager import risk_manager
from .services.trade_engine import trade_engine
from .api.routes import router

# 设置日志
setup_logging()
logger = logging.getLogger(__name__)


class ConnectionManager:
    """WebSocket连接管理器"""
    
    def __init__(self):
        self.active_connections: List[WebSocket] = []
    
    async def connect(self, websocket: WebSocket):
        """连接WebSocket"""
        await websocket.accept()
        self.active_connections.append(websocket)
        logger.info(f"WebSocket连接已建立，当前连接数: {len(self.active_connections)}")
    
    def disconnect(self, websocket: WebSocket):
        """断开WebSocket连接"""
        if websocket in self.active_connections:
            self.active_connections.remove(websocket)
            logger.info(f"WebSocket连接已断开，当前连接数: {len(self.active_connections)}")
    
    async def send_personal_message(self, message: str, websocket: WebSocket):
        """发送个人消息"""
        try:
            await websocket.send_text(message)
        except Exception as e:
            logger.error(f"发送个人消息失败: {e}")
            self.disconnect(websocket)
    
    async def broadcast(self, message: str):
        """广播消息"""
        disconnected_connections = []
        
        for connection in self.active_connections:
            try:
                await connection.send_text(message)
            except Exception as e:
                logger.error(f"广播消息失败: {e}")
                disconnected_connections.append(connection)
        
        # 移除断开的连接
        for connection in disconnected_connections:
            self.disconnect(connection)
    
    async def send_json(self, data: Dict, websocket: WebSocket = None):
        """发送JSON数据"""
        import json
        message = json.dumps(data, ensure_ascii=False, default=str)
        
        if websocket:
            await self.send_personal_message(message, websocket)
        else:
            await self.broadcast(message)


# 全局连接管理器
manager = ConnectionManager()


@asynccontextmanager
async def lifespan(app: FastAPI):
    """应用生命周期管理"""
    # 启动时执行
    logger.info("正在启动A股指数期权自动交易系统...")
    
    try:
        # 初始化数据库
        await db_manager.initialize()
        logger.info("数据库初始化完成")
        
        # 启动行情服务
        await market_data_service.start()
        logger.info("行情服务启动完成")
        
        # 启动策略引擎
        await strategy_engine.start()
        logger.info("策略引擎启动完成")
        
        # 连接交易引擎
        # await trade_engine.connect_broker("华泰证券")
        
        logger.info("系统启动完成")
        
    except Exception as e:
        logger.error(f"系统启动失败: {e}")
        raise
    
    yield
    
    # 关闭时执行
    logger.info("正在关闭系统...")
    
    try:
        # 停止策略引擎
        await strategy_engine.stop()
        logger.info("策略引擎已停止")
        
        # 停止行情服务
        await market_data_service.stop()
        logger.info("行情服务已停止")
        
        # 断开交易引擎
        await trade_engine.disconnect_broker()
        
        # 关闭数据库连接
        await db_manager.close()
        logger.info("数据库连接已关闭")
        
        logger.info("系统已安全关闭")
        
    except Exception as e:
        logger.error(f"系统关闭失败: {e}")


# 创建FastAPI应用
app = FastAPI(
    title="A股指数期权自动交易系统",
    description="A股指数期权自动交易系统API",
    version="1.0.0",
    lifespan=lifespan
)

# 配置CORS
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

# 注册路由
app.include_router(router, prefix="/api")


@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
    """WebSocket端点"""
    await manager.connect(websocket)
    
    try:
        while True:
            # 接收客户端消息
            data = await websocket.receive_text()
            
            try:
                import json
                message = json.loads(data)
                message_type = message.get("type")
                
                if message_type == "ping":
                    # 心跳响应
                    await manager.send_json({"type": "pong", "timestamp": datetime.now().isoformat()}, websocket)
                
                elif message_type == "subscribe":
                    # 订阅特定数据
                    channel = message.get("channel")
                    await manager.send_json({
                        "type": "subscription_confirmed",
                        "channel": channel,
                        "timestamp": datetime.now().isoformat()
                    }, websocket)
                
                elif message_type == "get_status":
                    # 获取系统状态
                    status = await get_system_status()
                    await manager.send_json({
                        "type": "system_status",
                        "data": status,
                        "timestamp": datetime.now().isoformat()
                    }, websocket)
                
                else:
                    # 未知消息类型
                    await manager.send_json({
                        "type": "error",
                        "message": f"未知消息类型: {message_type}"
                    }, websocket)
                    
            except json.JSONDecodeError:
                await manager.send_json({
                    "type": "error",
                    "message": "无效的JSON格式"
                }, websocket)
                
    except WebSocketDisconnect:
        manager.disconnect(websocket)
    except Exception as e:
        logger.error(f"WebSocket错误: {e}")
        manager.disconnect(websocket)


async def broadcast_market_data(symbol: str, data: Dict):
    """广播行情数据"""
    try:
        message = {
            "type": "market_data",
            "symbol": symbol,
            "data": data,
            "timestamp": datetime.now().isoformat()
        }
        await manager.broadcast(message)
    except Exception as e:
        logger.error(f"广播行情数据失败: {e}")


async def broadcast_trade_signal(strategy_id: str, signal: Dict):
    """广播交易信号"""
    try:
        message = {
            "type": "trade_signal",
            "strategy_id": strategy_id,
            "signal": signal,
            "timestamp": datetime.now().isoformat()
        }
        await manager.broadcast(message)
    except Exception as e:
        logger.error(f"广播交易信号失败: {e}")


async def broadcast_risk_alert(alert: Dict):
    """广播风险告警"""
    try:
        message = {
            "type": "risk_alert",
            "alert": alert,
            "timestamp": datetime.now().isoformat()
        }
        await manager.broadcast(message)
    except Exception as e:
        logger.error(f"广播风险告警失败: {e}")


async def get_system_status() -> Dict:
    """获取系统状态"""
    try:
        # 获取策略状态
        strategies = strategy_engine.get_strategies()
        active_strategies = len([s for s in strategies if s.get("is_active", False)])
        
        # 获取行情服务状态
        market_status = market_data_service.is_running
        
        # 获取交易引擎状态
        trade_status = await trade_engine.get_broker_status()
        
        # 获取风控状态
        risk_status = risk_manager.get_risk_status()
        
        return {
            "system": {
                "status": "running",
                "timestamp": datetime.now().isoformat(),
                "uptime": "0:00:00"  # 这里应该计算实际运行时间
            },
            "strategies": {
                "total": len(strategies),
                "active": active_strategies,
                "list": strategies
            },
            "market": {
                "status": "running" if market_status else "stopped",
                "subscriptions": len(market_data_service.subscriptions)
            },
            "trade": trade_status,
            "risk": risk_status
        }
        
    except Exception as e:
        logger.error(f"获取系统状态失败: {e}")
        return {
            "error": str(e),
            "status": "error"
        }


# 启动定时任务
async def start_periodic_tasks():
    """启动定时任务"""
    try:
        while True:
            # 每5秒广播一次系统状态
            try:
                status = await get_system_status()
                await manager.broadcast({
                    "type": "system_status",
                    "data": status,
                    "timestamp": datetime.now().isoformat()
                })
            except Exception as e:
                logger.error(f"广播系统状态失败: {e}")
            
            await asyncio.sleep(5)
            
    except Exception as e:
        logger.error(f"定时任务错误: {e}")


# 启动定时任务
@app.on_event("startup")
async def startup_event():
    """启动事件"""
    # 启动定时任务
    asyncio.create_task(start_periodic_tasks())
    logger.info("定时任务已启动")


if __name__ == "__main__":
    import uvicorn
    
    logger.info("启动FastAPI服务器...")
    uvicorn.run(
        "main:app",
        host=settings.HOST,
        port=settings.PORT,
        reload=settings.DEBUG,
        log_level="info"
    )
